<?php

namespace app\db\model;

use think\Db;
use think\Model;
use think\Cache;

class DbTemplateRelationItem extends Model
{

    // 开启自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';
    protected $dbName     = 'db_template_relation_item';

    # --------------------------------- 查询类接口 START------------------------------------
    /**
     * 获取模块信息
     * @param int  $item_id 模块ID
     * @author MSQ 2021-8-2
    **/
    public function getDetails($item_id = 0,$template_id = 0,$field = '')
    {
        if (!$item_id || !$template_id) return [];
        $where = [
            'r.template_id' => $template_id,
            'r.status'      => 1,
            'i.status'      => 1,
        ];
        if (!$field) $field = 'r.item_id,i.item_key,i.parent_id,i.type,i.classify_rank,r.item_name,i.create_type,r.weight,r.show_status';
        if (is_array($item_id)) {
            $where['r.item_id'] = ['IN',$item_id];
            if (count(explode(',', $field)) == 1) {
                // 只取一个字段
                $info = db($this->dbName)->alias('r')
                    ->join('db_item i',' i.id = r.item_id')
                    ->where($where)
                    ->column($field);
            }else{
                $info = db($this->dbName)->alias('r')
                    ->join('db_item i',' i.id = r.item_id')
                    ->field($field)
                    ->where($where)
                    ->select();
            }
        }else{
            $where['r.item_id'] = $item_id;

            if (count(explode(',', $field)) == 1) {
                // 只取一个字段
                $info = db($this->dbName)->alias('r')
                    ->join('db_item i',' i.id = r.item_id')
                    ->where($where)
                    ->value($field);
            }else{
                $info = db($this->dbName)->alias('r')
                    ->join('db_item i',' i.id = r.item_id')
                    ->field($field)
                    ->where($where)
                    ->find();
            }
        }
        
        return $info;
    }
    /**
     * 根据模板ID获取目录类表
     * @param int  $database_id 数据库id
     * @param int  $template_id 模板ID
     * @param int  $is_hide     是否返回隐藏
     * @author MSQ 2021-8-9
    **/
    public function getTemplateDirectoryList($template_id = 0,$is_hide = 0)
    {
        if (!$template_id) return false;

        $where = [
            'i.type'   => 1, // 只查目录
            'r.status' => 1,
            'i.status' => 1,
            'r.template_id' => $template_id,
        ];
        if (!$is_hide) $where['r.show_status'] = 1;

        $field = 'r.id as relation_id,r.template_id,r.item_id,r.item_name,i.item_key,i.parent_id,r.weight,r.status,i.create_time,i.create_type';

        $directoryList = db($this->dbName)->alias('r')
            ->field($field)
            ->join('db_item i','i.id=r.item_id')
            ->where($where)
            ->order('r.weight DESC,i.weight DESC,r.id ASC')
            ->select();
        if (!$directoryList) return [];
        
        $directoryList = arrayGroupByKey($directoryList,'parent_id');    
        if (!isset($directoryList[0])) return [];//没有一级目录

        # 所有一级目录的下级 二级目录/一级模块
        # 用于返回给前端一级目录下有无数据从而限制能否添加二级目录(有数据不能添加 只有空的一级目录可以添加)
        $allFirstDirIds = array_column($directoryList[0],'item_id');
        $where = [
            'i.parent_id' => ['IN',$allFirstDirIds],
            'i.status'    => 1,
            'r.status'    => 1
        ];
        $childItem = db($this->dbName)->alias('r')
            ->join('db_item i','i.id=r.item_id')
            ->where($where)
            ->column('i.parent_id,i.id');
        
        $returnData = [];
        foreach ($directoryList[0] as $k => $v) {
            // $v['edit_status'] = false; // 固定返回给前端
            $v['invalid_parameter1'] = false; // 固定返回给前端 用于双击修改目录名
            $v['invalid_parameter2'] = false; // 固定返回给前端 用于收缩二级目录列表

            if (isset($directoryList[$v['item_id']]) && $directoryList[$v['item_id']]) {
                # 有二级目录
                foreach ($directoryList[$v['item_id']] as $k_child => $v_child) {
                    $directoryList[$v['item_id']][$k_child]['path_key'] = $v['item_key'].'|'.$v_child['item_key'];
                    // $directoryList[$v['item_id']][$k_child]['edit_status'] = false;
                    $directoryList[$v['item_id']][$k_child]['invalid_parameter1'] = false;// 固定返回给前端 用于双击修改二级目录名称
                    $directoryList[$v['item_id']][$k_child]['invalid_parameter2'] = false; // 固定返回给前端 用于悬浮删除二级目录
                }
                $v['items'] = $directoryList[$v['item_id']];
            } else {
                $v['items'] = [];
            }
            # 是否有子目录/模块
            $v['has_child'] = true;
            if (!@$childItem[$v['item_id']]) $v['has_child'] = false;

            $returnData[] = $v;
        }
        return $returnData;
    }
    /**
     * 根据模板id和目录id获取目录下的item和问题（不获答案）
     * @param  [type] $template_id  模板id
     * @param  [type] $item_id      目录id
     * @param  [type] $need         need_question:需要问题 need_option:需要问题的选项 need_answer:需要回答 need_hide:需要隐藏
     * @return [type]               [description]
     * @author MSQ 2021-8-9
     */
    public function getTemplateItemQuestionList($template_id = 0,$item_id = 0,$need = false)
    {
        if (!$template_id || !$item_id) return false;
        if ($need === false) $need = model('DbTemplateRelationQuestion')->getQuestionListAllNeed();

        # 是否需要返回问题
        $need_question = in_array('need_question', $need) ? true : false;

        # 获取模板下的所有模块（包括一级和二级）
        # 获取模板下的一级模块
        $where_item_list = [
            'r.template_id'  => $template_id,
            'r.status'       => 1,//显示
            'i.type'         => 2,//模块
            'i.status'       => 1,//未删除
            'i.parent_id'    => $item_id,//旧版是查出模板所有模块后只处理目录下模块，这里是先找目录下一级再找二级，避免查出所有模块造成浪费
        ];
        # 是否展示
        if (!in_array('need_hide',$need)) $where_item_list['r.show_status'] = 1;

        //先获取模板下所有显示的模块列表
        $field = 'r.id as relation_id,r.template_id,r.item_id,r.item_name,i.item_key,i.create_type,i.parent_id,r.weight,i.create_time,r.show_status';

        # 该目录下所有一级模块
        $firstItemList = db($this->dbName)->alias('r')
            ->join('db_item i',' i.id = r.item_id')
            ->field($field)
            ->where($where_item_list)
            ->order('r.weight DESC,i.weight DESC,i.id ASC')
            ->select();

        if (!$firstItemList) return [];
        $firstItemIds = array_column($firstItemList,'item_id');

        # 一级模块录下所有二级模块
        $where_item_list['i.parent_id'] = ['IN',$firstItemIds];
        $secondItemList = db($this->dbName)->alias('r')
            ->join('db_item i','i.id = r.item_id')
            ->field($field)
            ->where($where_item_list)
            ->order('r.weight DESC,i.weight DESC,i.id ASC')
            ->select();

        # 合并一二级模块 并按层级组装
        $item_list = array_merge($firstItemList,$secondItemList);
        $item_list = arrayGroupByKey($item_list,'parent_id');
        $item_info = $item_list[$item_id];
        foreach ($item_info as $k => $v) {
            $item_info[$k]['second_item'] = [];
            if (!isset($item_list[$v['item_id']]) || !$item_list[$v['item_id']]) continue;

            $item_info[$k]['second_item'] = $item_list[$v['item_id']];   
            if (!$need_question) continue;
            foreach ($item_info[$k]['second_item'] as $k_q => $v_q) {
                //获取对应item下的问题及选项等
                $item_info[$k]['second_item'][$k_q]['question_answer_list'] = [];
                $item_info[$k]['second_item'][$k_q]['question_lists'] = model('DbTemplateRelationQuestion')->getQuestionListByItemId($template_id,$v_q['item_id'],$need);
                # 固定返回给前端
                $item_info[$k]['second_item'][$k_q]['invalid_parameter'] = false;
            }
        }
        $cacheKey = model('DbTemplateRelationQuestion')->getQuestionListCacheKey($template_id,$item_id,$need);
        # 缓存变量列表
        Cache::tag('question_list_'.$template_id)->set($cacheKey,$item_info);
        /*if ($redisKey) {
            $redis = MyRedis::getInstance();
            # 缓存列表 MSQ 2021-8-9
            $redis->hset($redisKey,$item_id,serialize($item_info));
        }*/
        return $item_info;
    }
    /**
     * 检测所选模板下 parent_id 下是否已有同名的item存在
     * @param  [type] $template_id 模板id
     * @param  [type] $item_name   item名称
     * @param  [type] $parent_id   上级所属item_id 可为0
     * @param  [type] $ignore_id   需要忽略的item_id（如编辑时不需要检测跟自己重复）
     * @return [type]                 [description]
     * @author MSQ  2021-8-10
     */
    public function checkItemExistByItemName($template_id = 0,$item_name = '',$parent_id = 0,$ignore_id = 0)
    {
        if (!$template_id || !$item_name) return false;
         $where = [
            'r.template_id' => $template_id,
            'i.parent_id'   => $parent_id,
            'r.item_name'   => $item_name,
            'i.status'      => 1,//未删除
            'r.status'      => 1,//未删除
        ];
        if ($ignore_id && is_array($ignore_id)) {
            $where['r.item_id'] = ['NOT IN',$ignore_id];
        } elseif ($ignore_id && $ignore_id) {
            $where['r.item_id'] = ['NEQ',$ignore_id];
        }
        # 检测当前模板当前模块下是否已经有一样的item
        $checkExist = db($this->dbName)->alias('r')
            ->join('db_item i','i.id = r.item_id')
            ->field('r.id as relation_id,r.item_id,r.item_name,i.parent_id')
            ->where($where)
            ->find();
        return $checkExist;
    }
    /**
     * 获取子目录/模块
     * @param  [type] $item_id     目录/模块id 0为获取模板下所有一级目录(适用于创建总库时递归处理模块)
     * @param  [type] $template_id 模板id
     * @param  [type] $field       字段
     * @return [type]              [description]
     * @author MSQ  2021-8-10
     */
    public function getChildItem($item_id = 0,$template_id = 0,$field = '')
    {
        if (!$template_id) return [];
        if (!is_array($item_id)) $item_id = [$item_id];
        
        $where = [
            'i.parent_id'   => ['IN',$item_id],
            'r.template_id' => $template_id,
            'r.status'      => 1,
            'i.status'      => 1,
        ];
        if (!$field) $field = 'i.id,i.item_key,i.parent_id,i.type,i.classify_rank,r.item_id,r.item_name';
        if ($field && $field != '*' && count(explode(',', $field)) == 1) {
            // 只取一个字段
            $info = db($this->dbName)->alias('r')
                ->join('db_item i',' i.id = r.item_id')
                ->where($where)
                ->column($field);
        }else{
            $info = db($this->dbName)->alias('r')
                ->join('db_item i',' i.id = r.item_id')
                ->field($field)
                ->where($where)
                ->select();
        }
        
        return $info;
    }
    /**
     * 获取模板二级模块
     * 用于新增总库自定义模板/编辑模块变量右侧列表可选模块
     * @param  [type] $template_id    模板id
     * @return [type]                 [description]
     * @author MSQ  2021-8-11
     */
    public function getTemplateSecondItem($template_id = 0)
    {
        if (!$template_id) return false;
        $where = [
            'i.type'           => 2,
            'i.classify_rank'  => 2,
            'r.template_id'    => $template_id,
            'r.status'         => 1,
            'i.status'         => 1,
        ];
        $field = 'r.item_id,r.item_name,i.item_key,i.parent_id,r.show_status';
        $list = db($this->dbName)->alias('r')
            ->join('db_item i',' i.id = r.item_id')
            ->field($field)
            ->where($where)
            ->order('r.weight DESC, r.id ASC')
            ->select();
        if (!$list) return [];
        return $list;
    }
    /**
     * 根据二级模块获取相关信息
     * 用于新增总库自定义模板/编辑模块变量右侧列表选择二级模块后渲染期目录及变量
     * @param  [type] $template_id 模板id
     * @param  [type] $item_id     二级模块id
     * @author MSQ 2021-8-11
     */
    public function getInfoBySecondItemId($template_id = 0,$item_id = 0)
    {
        if (!$template_id || !$item_id) return false;

        # 是否是二级模块
        $itemInfo = $this->getDetails($item_id,$template_id);

        if (!$itemInfo || ($itemInfo['type'] != 2 || $itemInfo['classify_rank'] != 2)) return false;
        $returnData['itemInfo'] = $itemInfo;
        $returnData['itemInfo']['invalid_parameter'] = false;// 固定返回给前端

        # 上级信息 即一二级目录，一级模块
        // $superiorInfo = $this->getItemSuperiorInfo($template_id,$item_id);
        // $returnData['superiorInfo'] = $superiorInfo;

        $need = ['need_question','need_option','need_hide'];
        $question_list = model('DbTemplateRelationQuestion')->getQuestionListByItemId($template_id,$item_id,$need);
        # 模块下变量信息
        $returnData['question_list'] = $question_list;

        return $returnData;
    }
    /**
     * 获取模块上级信息 
     * 递归至一级目录
     * @param  [type] $template_id 模板id
     * @param  [type] $item_id     目录/模块id
     * @author MSQ 2021-8-11
     */
    public function getItemSuperiorInfo($template_id = 0,$item_id = 0,$data = [])
    {
        if (!$template_id || !$item_id) return false;

        # 当前目录/模块信息
        $selfItem = $this->getDetails($item_id,$template_id);
        array_push($data,$selfItem);
        # 无上级 已找到顶级目录
        if (!$selfItem['parent_id']) return $data;

        return $this->getItemSuperiorInfo($template_id,$selfItem['parent_id'],$data);
    }
    /**
     * 检测模板与模块是否已关联
     * @param  [type] $template_id 模板id
     * @param  [type] $item_id     目录/模块id
     * @author MSQ 2021-8-11
     */
    public function checkExistRelationItem($template_id = 0,$item_id = 0)
    {
        if (!$template_id || !$item_id) return false;
        # 是否已关联过
        $where = [
            'template_id' => $template_id,
            'item_id'     => $item_id,
            'status'      => 1,
        ];
        return $this->where($where)->find();
    }
    /**
     * 获取模板关联的所有目录/模块
     * @param  [type] $template_id 模板id
     * @author MSQ 2021-8-25
     */
    public function getTemplateItemList($template_id = 0,$is_hide = 0,$field = '')
    {
        $where = [
            'r.template_id' => $template_id,
            'r.status'      => 1,
            'i.status'      => 1,
        ];
        if (!$is_hide) $where['r.show_status'] = 1;

        if (!$field) $field = 'i.id,i.item_key,i.parent_id,i.type,i.classify_rank,r.item_id,r.item_name';

        $info = db($this->dbName)->alias('r')
            ->join('db_item i',' i.id = r.item_id')
            ->field($field)
            ->where($where)
            ->select();
        return $info;
    }
    /**
     * 获取顶级itemName
     * 作用于导出病例表头变量名路径
     * @param  [type] $template_id 模板id
     * @author MSQ 2021-8-25
     */
    function getTopLevelItemName($template_id = 0,$parent_id = 0){
        $itemInfo = $this->getDetails($parent_id,$template_id);

        if ($itemInfo['parent_id']){
            return $this->recursiveGetParItemName($template_id,$itemInfo['parent_id']);
        }

        return $itemInfo['item_name'];
    }
     /**
     * 递归获取父级模块名
     * @param  [type] $template_id 模板id
     * @param  [type] $parent_id   父级id
     * @author MSQ 2021-8-25
     */
    function recursiveGetParItemName($template_id = 0,$parent_id = 0,$item_name = ''){
        $itemInfo = $this->getDetails($parent_id,$template_id);

        if ($itemInfo){
            $names = $item_name.'-'.$itemInfo['item_name'];
        }else{
            $names = $item_name;
        }
        if ($itemInfo['parent_id']){
            return $this->recursiveGetParItemName($itemInfo['parent_id'],$names);
        }
        return $names;
    }
    /**
     * 自定义SQL
     * @author MSQ 2021-9-1
     */
    public function customQuery($where = [],$field = '')
    {

        $where['r.status'] = 1;
        $where['i.status'] = 1;

        if (!$field) $field = 'r.item_id,i.item_key,i.parent_id,i.type,i.classify_rank,r.item_name,i.create_type,r.weight,r.show_status';

        $list = db($this->dbName)->alias('r')
            ->field($field)
            ->join('db_item i','r.item_id=i.id')
            ->where($where)
            ->select();

        return $list;
    }
    # ---------------------------------- 查询类接口 END-------------------------------------
   
    # --------------------------------- 验证类接口 START------------------------------------
    /**
     * 验证item设置
     * @param [type] $database_id  数据库id
     * @param [type] $template_id  模板id
     * @param [type] $parent_id    父级id
     * @param [type] $item_name    名称
     * @param [type] $item_id      有则编辑无则新增
     * @param [type] $type         类型 1目录2模块
     * @author MSQ   2021-8-10
     */
    public function checkSetItem($database_id = 0,$template_id = 0,$parent_id = 0,$item_name = '',$item_id = 0,$type = 0)
    {
        if (!$database_id || !$template_id || !$item_name || !$type) return ['code' => 0,'msg' => '参数错误'];
        if ($type == 2 && !$parent_id) return ['code' => 0,'msg' => '模块必须有上级'];

        # 是否为总库操作
        $dbParId = model('DbDatabase')->getDetails($database_id,'parent_id');
        if ($dbParId) return ['code' => 0,'msg' => '子库不允许操作'];

        if ($item_id) {
            # 是否是自定义item
            $itemInfo = model('DbItem')->getDetails($item_id);
            if (!$itemInfo) return ['code' => 0,'msg' => '目录/模块不存在'];

            if ($itemInfo['create_type'] != 1) return ['code' => 0,'msg' => '系统创建不可更改'];
        }
        
        # 检测同名
        $checkExist = $this->checkItemExistByItemName($template_id,$item_name,$parent_id,$item_id);
        if ($checkExist) return ['code' => 0,'msg' => '名称已存在']; 

        return ['code' => 1,'msg' => ''];
    }
    /**
     * 验证item是否可删除
     * @param [type] $database_id 数据库id
     * @param [type] $template_id 模板id
     * @param [type] $item_id     目录/模块id
     * @author MSQ   2021-8-10
     */
    public function checkDeleteItem($database_id = 0,$template_id = 0,$item_id = 0)
    {
        if (!$database_id || !$template_id || !$item_id) return ['code' => 0,'msg' => '参数错误'];

        # 是否为总库操作
        $dbParId = model('DbDatabase')->getDetails($database_id,'parent_id');
        if ($dbParId) return ['code' => 0,'msg' => '子库不允许操作'];

        $typeText = ['未知','目录','模块'];

        $itemInfo = model('DbItem')->getDetails($item_id);
        if (!$itemInfo) return ['code' => 0,'msg' => $typeText[$itemInfo['type']].'不存在'];

        if ($itemInfo['create_type'] != 1) return ['code' => 0,'msg' => '系统'.$typeText[$itemInfo['type']].',不予删除'];
        # 有没有下级
        $childItem = $this->getChildItem($item_id,$template_id);
        if ($childItem) return ['code' => 0,'msg' => $typeText[$itemInfo['type']].'存在下级，不予删除'];

        # 删的是二级模块 模块下是否有变量
        if ($itemInfo['type'] == 2 && $itemInfo['classify_rank'] == 2) {
            $hasQuestion = model('DbTemplateRelationQuestion')
                ->where(['item_id' => $item_id,'status' => 1])
                ->value('question_id');
            if ($hasQuestion) return ['code' => 0,'msg' => '模块下存在变量，不予删除'];
        }
        return ['code' => 1,'msg' => ''];
    }

    # ---------------------------------- 验证类接口 END-------------------------------------

    # ------------------------------- 数据处理类接口 START ----------------------------------
    /**
     * 引用模板-递归同步目录/模块
     * 适用于创建总库-引用模板 从一级目录递归至二级模块
     * 为避免频繁连接数据库 该方法只新增主表 组装关联数据批量新增 
     * @param [type] $origin_template_id 来源模板id 用于读取原模板变量及选项
     * @param [type] $template_id        需要生成关联的模板id
     * @param [type] $database_id        需要生成关联的数据库id
     * @param [type] $origin_parent_id   来源模板上级目录/模块id 读取原模板下级 0为一级目录
     * @param [type] $parent_id          新生成的上级模块id 0为一级目录
     * @param [type] $basicItemIds       基础信息相关模块id 主表不新增仅新增引用表
     * @param [type] $usercare_id        医务id
     * @param [type] $relationItemData   需要同步添加的目录/模块关联数据
     * @author MSQ   2021-9-2
     */
    public function recursionSyncItemForQuoteTemplate($origin_template_id = 0,$template_id = 0,$database_id = 0,$usercare_id = 0,$origin_parent_id = 0,$parent_id = 0,$basicItemIds = [],&$relationItemData = [])
    {
        if (!$origin_template_id || !$template_id || !$database_id) return false;

        # 获取取原模板下级目录/模块
        $field = 'i.*,r.item_name item_name2,r.weight relation_weight,r.show_status';
        $childItem = $this->getChildItem($origin_parent_id,$origin_template_id,$field);

        # 循环下级目录/模块
        foreach ($childItem as $key => $data) {
            # 是否需要添加主表 
            if (in_array($data['id'],$basicItemIds)) {
                # 基础信息相关变量无需添加仅添加关联即可
                $item_id = $data['id'];
            }else{
                # 非基础信息相关模块需要添加
                $addItem = [
                    'item_name'     => $data['item_name'],
                    'item_key'      => $data['item_key'].'&'.uniqid(),
                    'parent_id'     => $parent_id,
                    'type'          => $data['type'],
                    'classify_rank' => $data['classify_rank'],
                    'weight'        => $data['weight'],
                    'create_type'   => $data['create_type'],
                    'template_id'   => $template_id,
                    'usercare_id'   => $usercare_id,
                ];
                $item_id = model('DbItem')->addData($addItem);
            }
            if (!$item_id) return false;

            # 组装模块关联数据
            # 此处不新增关联表数据 避免频繁连接数据库 递归完成后在外部批量新增
            $relationItemData[] = [
                'item_id'     => $item_id,
                'item_name'   => $data['item_name2'],
                'database_id' => $database_id,
                'template_id' => $template_id,
                'weight'      => $data['relation_weight'],
                'show_status' => $data['show_status'],
            ];
            if ($data['type'] == 2 && $data['classify_rank'] == 2) {
                # 二级模块 停止递归目录/模块 开始同步变量&选项
                $res = model('DbTemplateRelationQuestion')->syncQuestionByItemIdForQuoteTemplate($origin_template_id,$template_id,$database_id,$data['id'],$item_id,$basicItemIds,$usercare_id);
            }else{                
                # 一级目录/二级目录/一级模块继续递归同步下一层数据
                $res = $this->recursionSyncItemForQuoteTemplate($origin_template_id,$template_id,$database_id,$usercare_id,$data['id'],$item_id,$basicItemIds,$relationItemData);
            }
            if (!$res) return false;
        }
        return true;
    }
    /**
     * 根据模板ID生成item关联
     * 适用于创建子库-引用模板
     * @param [type] $origin_template_id 来源模板id
     * @param [type] $template_id        需要生成关联的模板id
     * @param [type] $database_id        需要生成关联的数据库id
     * @param [type] $where_ori          自定义where
     * @author MSQ   2021-8-3
     */
    public function addTemplateRelationItemByTemplateId($origin_template_id = 0,$template_id = 0,$database_id = 0,$where_ori = [])
    {
        if (!$origin_template_id || !$template_id || !$database_id) return false;
        if (!$where_ori) {
            # 无自定义where
            $where_ori = [
                'template_id' => $origin_template_id
            ];
        }
        # 固定查询status
        $where_ori['status'] = 1;
        
        # 原模板关联的item
        $relationList = db($this->dbName)->where($where_ori)->select();
        if (!$relationList) return true;

        $newRelationList = array_chunk($relationList,1000);
        foreach ($newRelationList as $k_a => $v_a) {
            $addTemplateRelationData = [];
            foreach ($v_a as $k_b => $v_b) {
                $addTemplateRelationData[] = [
                    'template_id'   => $template_id,
                    'database_id'   => $database_id,
                    'item_id'       => $v_b['item_id'],
                    'item_name'     => $v_b['item_name'],
                    'weight'        => $v_b['weight'],
                    'show_status'   => $v_b['show_status'],
                ];
            }
            // $res = $this->saveAll($addTemplateRelationData);
            $res = $this->setAttr('id',null)->isUpdate(false)->saveAll($addTemplateRelationData);
            if (!$res) return false;
        }
        return true;
    }
    
    /**
     * 编辑目录/模块
     * @param  [type] $template_id  模板id
     * @param  [type] $parent_id    上级所属item_id 可为0
     * @param  [type] $item_name    item名称
     * @param  [type] $ignore_id    需要忽略的item_id（如编辑时不需要检测跟自己重复）
     * @return [type]               [description]
     * @author MSQ  2021-8-10
     */
    public function setItem($data = [])
    {
        if (!$data) return true;
        if (!$data['item_id'] || !$data['template_id']) return false;

        $itemInfo = $this->getDetails($data['item_id'],$data['template_id']);
        if (!$itemInfo) return false;

        # 更新relationItem
        $where = [
            'item_id'     => $data['item_id'],
            'template_id' => $data['template_id'],
            'status'      => 1
        ];
        # 总库更新数据  子库更新数据  总表更新数据
        $saveData = $saveChildData = $itemSaveData = [];
        if (isset($data['item_name']) && ($data['item_name'] != $itemInfo['item_name'])) {
            $saveData['item_name'] = $data['item_name'];
            $saveChildData['item_name'] = $data['item_name'];
            $itemSaveData['item_name'] = $data['item_name'];
        }
        if (isset($data['parent_id']) && ($data['parent_id'] != $itemInfo['parent_id'])) {
            $itemSaveData['parent_id'] = $data['parent_id'];
            // $saveChildData['parent_id'] = $data['parent_id'];
        }
        if (isset($data['type']) && ($data['type'] != $itemInfo['type'])) {
            $itemSaveData['type'] = $data['type'];
            // $saveChildData['type'] = $data['type'];
        }
        if (isset($data['classify_rank']) && ($data['classify_rank'] != $itemInfo['classify_rank'])) {
            $itemSaveData['classify_rank'] = $data['classify_rank'];
            // $saveChildData['classify_rank'] = $data['classify_rank'];
        }
        if (isset($data['show_status']) && ($data['show_status'] != $itemInfo['show_status'])) {
            $saveData['show_status'] = $data['show_status'];
        }
        if (isset($data['weight']) && ($data['weight'] != $itemInfo['weight'])) {
            $saveData['weight'] = $data['weight'];
        }
        if (!$saveData && !$itemSaveData && !$saveChildData) return true;

        $saveRes = $this->update($saveData,$where);
        if ($saveRes === false) return false;

        # 更新其下子库关联变量 权重不更新 避免总库影响到子库自己的权重
        $relevantTemplateId = [$data['template_id']];
        if ($saveChildData) {
            # 总库下引用该目录/模块的子库模板
            $childTemplateId = model('DbTemplate')->getChildDbOrTemplate($data['template_id'],2,0);
            $childTemplateId = array_filter($childTemplateId);
            if ($childTemplateId) {
                $where['template_id'] = ['IN',$childTemplateId];
                $saveRes = $this->update($saveChildData,$where);
                # 更新有关联想子库
                if ($saveRes === false) return false;
                $relevantTemplateId = $relevantTemplateId+$childTemplateId;             
            }
        }
        if (!$itemSaveData) return true;

        # 是否有跨总库模板引用该目录/模块 目前是一个总库对应一套目录&模块 不存在跨总库一说 且模块上级是可更改的 若是只改关联表的话数据将不同步
        /*$where['template_id'] = ['NOT IN',$relevantTemplateId];
        $isOtherSync = db($this->dbName)->where($where)->value('id');
        if ($isOtherSync) return true;*/

        # 没有其他跨库引用 即只有该总库及其子库引用 同步修改item表数据
        $saveRes = model('DbItem')->update($itemSaveData,['id' => $data['item_id'],'status' => 1]);
        if (!$saveRes) return false;

        return true;
    }
    /**
     * 创建关联目录/模块
     * @param [type] $template_id 模板id
     * @param [type] $item_id     目录/模块id
     * @author MSQ   2021-8-10
     */
    public function createRelationItem($data = [])
    {
        if ((!isset($data['template_id']) || !$data['template_id']) || (!isset($data['item_id']) || !$data['item_id'])) return false;
        $itemInfo = model('DbItem')->getDetails($data['item_id']);
        if (!$itemInfo) return false;

        if (!$data['database_id']) $data['database_id'] = model('DbTemplate')->getDetails($data['template_id'],'database_id');
        if (!$data['database_id']) return false;

        $isRelation = $this->checkExistRelationItem($data['template_id'],$data['item_id']);
        if ($isRelation) return $isRelation['id'];

        $addData = [
            'database_id'   => $data['database_id'],
            'template_id'   => $data['template_id'],
            'item_id'       => $data['item_id'],
            'item_name'     => isset($data['item_name']) ? $data['item_name'] : $itemInfo['item_name'],
            'weight'        => isset($data['weight']) ? $data['weight'] : $itemInfo['weight'],
            'show_status'   => isset($data['show_status']) ? $data['show_status'] : 1,
            /*'parent_id'     => isset($data['parent_id']) ? $data['parent_id'] : 0,
            'type'          => $data['type'],
            'classify_rank' => $data['classify_rank'],*/
        ];
        $this->setAttr('id',null)->isUpdate(false)->save($addData);
        if (!isset($this->id)) return false;        
        return $this->id;
    }
    /**
     * 删除目录/模块
     * @param [type] $template_id 模板id
     * @param [type] $item_id     目录/模块id
     * @author MSQ   2021-8-10
     */
    public function deleteItem($template_id = 0,$item_id = 0)
    {
        if (!$template_id || !$item_id) return false;

        # 总库下引用该目录/模块的模板 含自己
        $relevantTemplateId = model('DbTemplate')->getChildDbOrTemplate($template_id,2);
        $relevantTemplateId = array_filter($relevantTemplateId);
        if (!$relevantTemplateId) return false;

        $saveData = ['status' => 0];
        # 更新relationItem
        $where = [
            'item_id'     => $item_id,
            'template_id' => ['IN',$relevantTemplateId],
            'status'      => 1
        ];
        $saveRes = $this->update($saveData,$where);

        if (!$saveRes) return false;
        # 是否有跨总库模板引用该目录/模块
        $where['template_id'] = ['NOT IN',$relevantTemplateId];
        $isOtherSync = db($this->dbName)->where($where)->value('id');
        if ($isOtherSync) return true;

        # 没有其他跨库引用 即只有该总库及其子库引用 同步修改item表数据
        $saveRes = model('DbItem')->update($saveData,['id' => $item_id,'status' => 1]);
        if (!$saveRes) return false;

        return true;
    }
    /**
     * 删除整个模板下目录/模块
     * @param [type] $template_id 模板id
     * @author MSQ   2021-8-21
     */
    public function deleteDataByTemplate($template_id = [])
    {
        if (!$template_id) return false;
        if (!is_array($template_id)) $template_id = [$template_id];

        $where = [
            'status'      => 1,
            'template_id' => ['IN',$template_id]
        ];
        # 所有要删除的item
        $relevantItem = db($this->dbName)->where($where)->group('item_id')->column('item_id');
        if (!$relevantItem) return false;

        # 是否有跨总库模板引用该目录/模块
        $where['item_id'] = ['IN',$relevantItem];
        $where['template_id'] = ['NOT IN',$template_id];
        # 查找跨总库的item
        $otherSyncItem = db($this->dbName)->where($where)->group('item_id')->column('item_id');

        $where = [
            'status'      => 1,
            'template_id' => ['IN',$template_id]
        ];
        # 删除相关模板的关联item
        $res = $this->update(['status' => 0],$where);
        if (!$res) return false;
        
        # 差集 即没有跨总库引用 可删除总表item
        $deleteItems = array_diff($relevantItem,$otherSyncItem);
        if (!$deleteItems) return true;

        $res = model('DbItem')->deleteItemByIds($deleteItems);
        if (!$res) return false;

        return true;
    }
    # --------------------------------- 数据处理类接口 END ----------------------------------
    

}
